#include<iostream>
#include<cstring>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>

using namespace std;

// int main()
// {   
//     char str[1024];
//     snprintf(str,sizeof(str),"haha");//snprintf函数在每次向字符串中写数据的时候会先清除
//     cout<<str<<endl;
//     return 0;
// }

int main()
{
    //建立管道
    int tmp[2]={0};
    //int tmpp[2]={0};
    int n=pipe(tmp);
    //pipe(tmpp);
    //cout<<tmp[0]<<" "<<tmp[1]<<" "<<tmpp[0]<<" "<<tmpp[1]<<endl;3 4 5 6
    if(n==-1)
    {
        cout<<"管道建立失败"<<endl;
        exit(-1);
    }

    //创建子进程，父子进程指向同一个文件
    int id=fork();
    if(id<0)
    {
        cout<<"进程创建失败"<<endl;
        exit(-1);
    }

    //child-w
    if(id==0)
    {
        close(tmp[0]);//关闭读文件
        char str[1024];int cnt=10000;
        while(1)
        {
            //sleep(1);//管道没数据时，读端口会进行等待，直到有数据为止
            //sprintf(str,"hello parent, I am chilld,mypid = %d,cnt = %d",getpid(),cnt--);
            snprintf(str,sizeof(str)-1,"hello parent, I am chilld,mypid = %d,cnt = %-2d",getpid(),cnt--);//防止str被写穿，预留\0
            write(tmp[1],str,strlen(str));//写入到文件中（文件中是不存在\0的）
            cout<<"write------------------"<<cnt<<endl;

            //close(tmp[1]);//写一次就关闭
            break;
            //if(cnt==0)break;
        }
        while(1);
        //exit(0);
        //结束if语句就算子进程退出
    }
    //parent-r
    if(id>0)
    {
        close(tmp[1]);//关闭写文件
        char buffer[1024];
        while(1)
        {
           //sleep(1);//等待子进程，让子进程一直写
            //管道被写满的话，写端口会进行等待，直到被读走数据，管道有空间为止
            int sz = read(tmp[0],buffer,sizeof(buffer)-1);//防止读入buffer的数据超出临时空间，预留\0
            //正常情况sz=0的时候，是因为管道没数据，写端口阻塞
            if(sz>0)
            {
                buffer[sz]=0;//字符串末尾加0
                cout<<buffer<<"  parent_id:"<<getpid()<<endl;
            }
            else if(sz==0)
            {
                cout<<"写端关闭了文件描述符或者子进程退出"<<endl;
                break;
            }
            // close(tmp[0]);
            // cout<<"读端关闭"<<endl;
            // break;
        }
        sleep(10);
        pid_t rid = waitpid(id,nullptr,0);//等待子进程退出
        if(rid==id)
        {
            cout<<"wait ok"<<endl;
        }
    }

   
    return 0;
}
